package genalgoritm.count;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.math.genetics.AbstractListChromosome;
import org.apache.commons.math.genetics.BinaryChromosome;
import org.apache.commons.math.genetics.Chromosome;

public class RealChromosome extends BinaryChromosome {
	private static Integer LENGTH = 4;
	private double x;
	private ArrayList<Integer> chr = new ArrayList<Integer>(); 

	public RealChromosome(double x) {
		super(getChromosome(x));
		setX(x);
	}

	public RealChromosome(List<Integer> representation) {
		super(representation);
		setX(getXByChromosome(representation));
	}

	private static List<Integer> getChromosome(Double x) {
		x = ((Integer)x.intValue()).doubleValue();
		ArrayList<Integer> out = new ArrayList<Integer>(); 
		while (x!=0){
			if (x%2==0) {
				out.add(0);
			} else {
				out.add(1);
				x--;
			}
			x=x/2;
		}
		while (out.size()<LENGTH){
			out.add(0);
		}
		return out;
	}
	private static Double getXByChromosome(List<Integer> chr) {
		Double x = 0.0;
		for (int index = 0; index<chr.size(); index++) {
			Integer gen = chr.get(index);
			if (gen==1) {
				x=x+Math.pow(2, index);
			}
		}
		return x.doubleValue();		
	}

	@Override
	public double fitness() {
		return Function.count(x);
	}

	@Override
	public int compareTo(Chromosome another) {
		int res = 0;
		if (another.fitness()>fitness()) {
			res = -1;
		}
		if (another.fitness()<fitness()) {
			res = 1;
		}
		if (another.fitness()==fitness()) {
			res = 0;
		}
		return res;
	}
	
	public double getX() {
		return x;
	}

	public String getChr() {
		String out = "";
		for (Integer integer : chr) {
			out = integer+out;
		}
		return out;
	}

	private void setChr(ArrayList<Integer> chr) {
		this.chr = chr;
	}

	public void setX(Double x) {
		this.x = x;
		setChr((ArrayList<Integer>) getChromosome(x));
	}

	@Override
	public AbstractListChromosome<Integer> newFixedLengthChromosome(
			List<Integer> representation) {
		return new RealChromosome(representation);
	}
	
	@Override
	public List<Integer> getRepresentation() {
		return chr;
	}

}
